﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NHINDirect
{
    public enum EntityPartType : byte
    {
        Header,
        HeaderBoundary,
        Body,
        Prologue,
        SubPart,
        Epilogue
    }

    public class EntityPart<T>
    {
        T m_type;
        StringSegment m_sourceText; // Text from the source message string: VERBATIM. Necessary for signatures etc.
        string m_text;

        public EntityPart(T type)
        {
            this.m_type = type;
            this.m_sourceText = StringSegment.Null;
        }

        public EntityPart(T type, StringSegment segment)
        {
            this.m_type = type;
            this.m_sourceText = segment;
        }

        public T Type
        {
            get
            {
                return this.m_type;
            }
            internal set
            {
                this.m_type = value;
            }
        }

        public StringSegment SourceText
        {
            get
            {
                return this.m_sourceText;
            }
            protected set
            {
                this.m_sourceText = value;
            }
        }

        public virtual string Text
        {
            get
            {
                if (this.m_text == null)
                {
                    this.m_text = this.m_sourceText.ToString();
                }

                return this.m_text;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                this.m_sourceText = new StringSegment(value);
            }
        }

        public override string ToString()
        {
            return this.Text;
        }
        
        internal void AppendText(string text)
        {
            this.m_text = this.Text + text;
        }
        
        internal virtual void AppendSourceText(StringSegment segment)
        {
            this.m_sourceText.Union(segment);
        }
    }

    public class EntityPart : EntityPart<EntityPartType>
    {
        public EntityPart(EntityPartType type)
            : base(type)
        {
        }
        
        public EntityPart(EntityPartType type, StringSegment segment)
            : base(type, segment)
        {
        }
    }
 }
